/**
 @file sys_usw_security.h

 @date 2010-2-26

 @version v2.0

---file comments----
*/

#ifndef SYS_USW_SECURITY_H_
#define SYS_USW_SECURITY_H_
#ifdef __cplusplus
extern "C" {
#endif

/***************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "sal.h"
#include "ctc_const.h"
#include "ctc_spool.h"
#include "ctc_security.h"
#include "ctc_l2.h"

/***************************************************************
 *
 *  Defines and Macros
 *
 ***************************************************************/

#define SYS_STMCTL_INVALID_OFFSET               CTC_MAX_UINT16_VALUE
#define SYS_STMCTL_MAX_PTR 256


#define SYS_SECURITY_DBG_OUT(level, FMT, ...) \
    do { \
        CTC_DEBUG_OUT(security, security, SECURITY_SYS, level, FMT, ##__VA_ARGS__); \
    } while (0);

#define SYS_SECURITY_DBG_FUNC()                          \
    { \
    SYS_SECURITY_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n",__FUNCTION__);\
    }

#define SYS_SECURITY_DBG_DUMP(FMT, ...)               \
    {                                                 \
    SYS_SECURITY_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, FMT, ##__VA_ARGS__);\
    }

#define SYS_SECURITY_DBG_INFO(FMT, ...)               \
    {                                                 \
    SYS_SECURITY_DBG_OUT(CTC_DEBUG_LEVEL_INFO, FMT, ##__VA_ARGS__);\
    }

#define SYS_SECURITY_DBG_ERROR(FMT, ...) \
    { \
    SYS_SECURITY_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, FMT, ##__VA_ARGS__);\
    }

struct sys_security_master_s
{
    ctc_security_stmctl_glb_cfg_t stmctl_cfg;
    uint8  flag;     /*ipsg*/
    uint8  limit_opf_type;
    uint8  stmctl_profile0_opf_type;
    uint8  stmctl_profile1_opf_type;
    uint8  storm_ctl_opf_type;
    uint8  hmac_opf_type;
    uint8  tcam_group[2];    /* create scl tcam group once*/
    uint8  hash_group[2];    /* create scl hash group once*/
    uint8  stmctl_glb_mode; /*refer to ctc_security_storm_ctl_glb_mode_t*/
    uint8  rsv;
    ctc_hash_t*  hmac_key_info;  /* for hmac sha key */
    ctc_spool_t* trhold_spool;
    ctc_spool_t* stmctl_spool;
    sal_mutex_t* sec_mutex;   /**< mutex for security */
    uint16  port_id[SYS_STMCTL_MAX_PTR];  /* port stormctl ptr map port id*/
    uint16  vlan_id[SYS_STMCTL_MAX_PTR]; /* vlan stormctl ptr map vlan id */
};
typedef struct sys_security_master_s sys_security_master_t;

extern sys_security_master_t* usw_security_master[CTC_MAX_LOCAL_CHIP_NUM_PP];

#define SYS_STMCTL_GET_TBL_RESRC_ID(op, offset, id) \
    { \
        if (CTC_SECURITY_STORMCTL_MODE_0 == usw_security_master[lchip]->stmctl_glb_mode) \
            id = CTC_SECURITY_STORM_CTL_OP_VLAN == op ? 1 : 0; \
        else if (CTC_SECURITY_STORMCTL_MODE_1 == usw_security_master[lchip]->stmctl_glb_mode \
            || CTC_SECURITY_STORMCTL_MODE_2 == usw_security_master[lchip]->stmctl_glb_mode) \
            id = offset < SYS_STMCTL_MAX_PTR*2 ? 0 : 1; \
    }

#define SYS_STMCTL_GET_TBL_INDEX_ID(offset, index) \
    { \
        if (CTC_SECURITY_STORMCTL_MODE_0 == usw_security_master[lchip]->stmctl_glb_mode) \
            index = offset >> 1; \
        else if (CTC_SECURITY_STORMCTL_MODE_1 == usw_security_master[lchip]->stmctl_glb_mode \
            || CTC_SECURITY_STORMCTL_MODE_2 == usw_security_master[lchip]->stmctl_glb_mode) \
            index = (offset < SYS_STMCTL_MAX_PTR*2 ? offset : (offset - SYS_STMCTL_MAX_PTR*2)) >> 1; \
    }

/****************************************************************************
 *
* Global and Declaration
*
*****************************************************************************/
struct sys_stmctl_profile_s
{
    uint8  op;  /*mean profile pool type*/
    uint8  is_y;

    uint8  rate_frac;
    uint8  rate_shift;
    uint8  threshold_shift;
    uint8  rsv[3];
    uint16 threshold;
    uint16 rate;

    uint32 profile_id;
};
typedef struct sys_stmctl_profile_s sys_stmctl_profile_t;
/***************************************************************
 *
 *  Functions
 *
 ***************************************************************/
extern int32
sys_usw_security_init(uint8 lchip, ctc_security_global_cfg_t* security_glb_cfg);

/**
 @brief De-Initialize security module
*/
extern int32
sys_usw_security_deinit(uint8 lchip);

/*port security*/
extern int32
sys_usw_mac_security_set_port_security(uint8 lchip, uint32 gport, bool enable);

extern int32
sys_usw_mac_security_get_port_security(uint8 lchip, uint32 gport, bool* p_enable);

/*mac limit*/
extern int32
sys_usw_mac_security_set_port_mac_limit(uint8 lchip, uint32 gport, ctc_maclimit_action_t action);
extern int32
sys_usw_mac_security_get_port_mac_limit(uint8 lchip, uint32 gport, ctc_maclimit_action_t* action);
extern int32
sys_usw_mac_security_set_vlan_mac_limit(uint8 lchip, uint16 vlan_id, ctc_maclimit_action_t action);
extern int32
sys_usw_mac_security_get_vlan_mac_limit(uint8 lchip, uint16 vlan_id, ctc_maclimit_action_t* action);
extern int32
sys_usw_mac_security_set_system_mac_limit(uint8 lchip, ctc_maclimit_action_t action);
extern int32
sys_usw_mac_security_get_system_mac_limit(uint8 lchip, ctc_maclimit_action_t* action);

/*learning limit*/

extern int32
sys_usw_mac_security_set_learn_limit(uint8 lchip, ctc_security_learn_limit_t* p_learn_limit);

extern int32
sys_usw_mac_security_get_learn_limit(uint8 lchip, ctc_security_learn_limit_t* p_learning_limit, uint32* p_running_num);

/*ip source guard*/
extern int32
sys_usw_ip_source_guard_add_entry(uint8 lchip, ctc_security_ip_source_guard_elem_t* p_elem);

extern int32
sys_usw_ip_source_guard_remove_entry(uint8 lchip, ctc_security_ip_source_guard_elem_t* p_elem);

/*storm control cfg*/
extern int32
sys_usw_storm_ctl_set_cfg(uint8 lchip, ctc_security_stmctl_cfg_t* stmctl_cfg);

extern int32
sys_usw_storm_ctl_get_cfg(uint8 lchip, ctc_security_stmctl_cfg_t* stmctl_cfg);

extern int32
sys_usw_storm_ctl_set_global_cfg(uint8 lchip, ctc_security_stmctl_glb_cfg_t* p_glb_cfg);

extern int32
sys_usw_storm_ctl_get_global_cfg(uint8 lchip, ctc_security_stmctl_glb_cfg_t* p_glb_cfg);

extern int32
sys_usw_hmac_add_sha_key(uint8 lchip, ctc_security_hmac_t* p_hmac);

extern int32
sys_usw_hmac_remove_sha_key(uint8 lchip, ctc_security_hmac_t* p_hmac);

extern int32
sys_usw_hmac_get_sha_key(uint8 lchip, ctc_security_hmac_t* p_hmac, uint32* p_key_index, uint8 flag);

/* if flag equal to 0 means getting key index and sha key, others getting key id */
extern int32
sys_usw_hmac_get_sha_key(uint8 lchip, ctc_security_hmac_t* p_hmac, uint32* p_key_index, uint8 flag);

/*port isolation*/

extern int32
sys_usw_port_isolation_set_route_obey_isolated_en(uint8 lchip, bool enable);

extern int32
sys_usw_port_isolation_get_route_obey_isolated_en(uint8 lchip, bool* p_enable);

extern int32
sys_usw_mac_security_set_fid_learn_limit_action(uint8 lchip, uint16 fid, ctc_maclimit_action_t action);

extern int32
sys_usw_mac_security_get_fid_learn_limit_action(uint8 lchip, uint16 fid, ctc_maclimit_action_t* action);

#ifdef __cplusplus
}
#endif

#endif

